﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using DAL.EstRec;
using System.Diagnostics;
using System.Collections;
using BAL.EstRec.FDVUtil;

namespace BAL.EstRec
{
    public delegate void EventHandler<XLSExportEvents>(object sender, XLSExportEvents e);

    public class ExcelRHQ
    {
        #region events
        public event EventHandler<XLSExportEvents> xlsCreated;

        public virtual void OnXlsCreatedEvent(XLSExportEvents e)
        {
            xlsCreated(this, e);
        }

        public event EventHandler<XLSExportEvents> xlsCreationError;

        public virtual void OnXlsCreationErrorEvent(XLSExportEvents e)
        {
            xlsCreationError(this, e);
        }
        #endregion
        private XLSData xlsArgs;
        XLSActionsProcess xlsProc; 
        AppConfs cnf;
        List<string> _failedXls;
        public List<string> failedXls
        {
            get { return _failedXls; }
            set { _failedXls = value; }
        }

        public string FDV_version { get; set; }
        public List<string> List_Recursos { get; set; }

        public ExcelRHQ(string FDV_version, List<string> List_Recursos)
        {
            this.FDV_version = FDV_version;
            this.List_Recursos = List_Recursos;
            this.xlsArgs = new XLSData();

            this.xlsArgs = new XLSData();
            this.cnf = new AppConfs();
        }


        public void ExportXLS(VMPublish vm)
        {
            this.failedXls = new List<string>();
            bool updateVersion = true;
            int published = 0;
            vm.Message = "Publicación "+published.ToString()+" / "+this.List_Recursos.Count();

            foreach (string s in List_Recursos)
            {
                try
                {
                    DataTable dt = new DataTable();
                    DataTable dt2 = new DataTable();

                    ExportExcel EE = new ExportExcel();

                    string Iniciativa = "";
                    int tiempoo = 0;

                    dt = SrvDB.ExecuteQuery("EXEC SP_GET_INICIATIVA_FDV @IDS = '" + s + "'");
                    Iniciativa = dt.Rows[0]["INICIATIVA"].ToString();
                    tiempoo = Int32.Parse(dt.Rows[0][1].ToString());

                    DataTable TablaFinal = new DataTable();
                    TablaFinal.Columns.Add("Iniciativa", typeof(string));
                    TablaFinal.Columns.Add("Cliente", typeof(string));

                    TablaFinal.Rows.Add("", Iniciativa);
                    TablaFinal.Rows.Add("Cliente", s);
                    List<Recurso> recursos=Recurso.GetRecursosList();

                    dt2 = SrvDB.ExecuteQuery("EXEC SP_GET_RECURSOS_FDV @IDS = '" + s + "' ,@VERSION = " + FDV_version);

                    int sum = 0;
                    int max = 0;
                    int totalpos = 0;
                    Recurso resRec = new Recurso();

                    try
                    {
                        resRec=(from o in recursos
                                where o.idRecurso==s
                                select o).First();
                    }catch(Exception ex)
                    {
                        ;
                    }

                    for (int i = 0; i < dt2.Rows.Count; i++)
                    {
                        string POS = "";
                        string Cantidad = "";


                        for (int j = 0; j < dt2.Columns.Count; j++)
                        {
                            if (j == 0)
                            {
                                POS = dt2.Rows[i][j].ToString();
                            }
                            else
                            {

                                Cantidad = dt2.Rows[i][j].ToString();
                            }
                        }

                        //sum += Int32.Parse(Cantidad);

                        

                        if(Int32.Parse(Cantidad)!=0)
                        {
                            sum += Int32.Parse(Cantidad) * resRec.tiempoImplementacion;
                            max += resRec.visitasSugeridas;
                        }
                            

                            //max = Int32.Parse(Cantidad)*;

                        
                        TablaFinal.Rows.Add(POS, Cantidad);
                        totalpos += (Convert.ToInt32(Cantidad) > 0) ? 1 : 0;
                    }

                    //sum *= tiempoo;
                    TablaFinal.Rows.Add("Tiempo de implementación", sum.ToString());
                    TablaFinal.Rows.Add("Visitas Sugeridas", max.ToString());

                    string unid = "";

                    unid += DateTime.Today.Year.ToString();
                    unid += (DateTime.Today.Month.ToString().Length == 1) ? "0" + DateTime.Today.Month.ToString() : DateTime.Today.Month.ToString();
                    unid += (DateTime.Today.Day.ToString().Length == 1) ? "0" + DateTime.Today.Day.ToString() : DateTime.Today.Day.ToString();
                    unid += (DateTime.Now.Hour.ToString().Length == 1) ? "0" + DateTime.Now.Hour.ToString() : DateTime.Now.Hour.ToString();
                    unid += (DateTime.Now.Minute.ToString().Length == 1) ? "0" + DateTime.Now.Minute.ToString() : DateTime.Now.Minute.ToString();
                    unid += (DateTime.Now.Second.ToString().Length == 1) ? "0" + DateTime.Now.Second.ToString() : DateTime.Now.Second.ToString();
                    string mil= DateTime.Now.Millisecond.ToString();
                    unid += ("000" +mil).Substring(("000" +mil).Length - 3);//(DateTime.Now.Millisecond.ToString().Length == 1) ? "0" + DateTime.Now.Millisecond.ToString() : DateTime.Now.Millisecond.ToString();
                    


                    string nombre = this.FDV_version + "_" + s + "_" + unid;

                    AppConfs ac = new AppConfs();
                    try
                    {
                        //obtiene el número de intentos de creación 
                        int numTry = 0;
                        int.TryParse(cnf.cnf.NumTryCreateXls, out numTry);
                        int currentTry = 0;

                        do
                        {
                            try
                            {
                                this.xlsProc = new XLSActionsProcess();
                                if (this.xlsProc.isExcelActive)
                                    this.xlsProc.KillExcel();


                                EE.DataToExcel2(TablaFinal, false, ac.cnf.PublicarRHQ + nombre + ".xlsx");   //+ s + ".xlsx");

                                numTry = 0;
                            }
                            catch (Exception exx)
                            {
                                numTry--;
                                currentTry++;
                                Console.WriteLine("Intento: " + currentTry + " fallido.");
                                this.failedXls.Add(ac.cnf.PublicarRHQ + nombre + ".xlsx");

                                this.xlsProc = new XLSActionsProcess();

                                if (this.xlsProc.isExcelActive)
                                    this.xlsProc.KillExcel();


                                if (numTry == 0)
                                    throw new Exception("No se pudo finalizar la creación del archivo Excel." + exx.Message + ". Intentos: " + currentTry.ToString());
                            }

                        } while (numTry > 0);
                    }
                    catch (Exception ex)
                    {
                        xlsArgs.nombre = ac.cnf.PublicarRHQ + nombre + ".xlsx";
                        xlsArgs.recursoId = s;
                        xlsArgs.version = FDV_version;
                        xlsArgs.msg = ex.Message;
                        OnXlsCreationErrorEvent(new XLSExportEvents() { xlsInfo = xlsArgs });
                        throw ex;
                    }

                    if (System.IO.File.Exists(ac.cnf.PublicarRHQ + nombre + ".xlsx"))  //+ s + ".xlsx");
                    {
                        xlsArgs.recurso = Recurso.GetRecursoData(s);
                        xlsArgs.nombre = ac.cnf.PublicarRHQ + nombre + ".xlsx";
                        xlsArgs.recursoId = s;
                        xlsArgs.version = FDV_version;
                        xlsArgs.totalPos = totalpos;
                        xlsArgs.iniciativa = Iniciativa;
                        xlsArgs.tiempoImplement = sum;
                        OnXlsCreatedEvent(new XLSExportEvents() { xlsInfo = xlsArgs });
                    }

                    published++;
                    vm.Message = "Publicación " + published.ToString() + " / " + this.List_Recursos.Count();
                }
                catch (Exception ex2)
                {
                    vm.ManualClose = true;
                    vm.Message = "Ocurrió un error al publicar. Valide que cuenta con red pmi y permisos necesarios para la publicación."
                                + "\nDetalles : [" + ex2.Message + "]";
                    updateVersion = false;
                    break;
                }
            }

            if (updateVersion)
            {
                long x = 0;
                if(Int64.TryParse(this.FDV_version,out x))
                {
                    FdvVersion.SetDatePublished(x);
                }
            }
        }//endfunc
    }// end class


    public class XLSData
    {
        public string nombre { get; set; }
        public string version { get; set; }
        public string recursoId { get; set; }
        public string msg { get; set; }

        public int totalPos { get; set; }
        public string iniciativa { get; set; }
        public int tiempoImplement { get; set; }
        public Recurso recurso { get; set; }
    }//end class

    public class XLSExportEvents : EventArgs
    {
        public XLSData xlsInfo { get; set; }

    }//end class

    public class XLSActionsProcess
    {
        private Hashtable ht;
        bool _isExcelActive;

        public bool isExcelActive
        {
            get { return _isExcelActive; }
            set { _isExcelActive = value; }
        }

        public XLSActionsProcess()
        {
            this.CheckExcellProcesses();
        }//constructor

        /// <summary>
        /// Verifica si esisten procesos de Excel corriendo.
        /// </summary>
        private void CheckExcellProcesses()
        {
            
            List<Process> lstProc = Process.GetProcessesByName("excel").ToList();
            ht = new Hashtable();

            if (lstProc.Count > 0)
            {
                lstProc.ForEach(
                        p=> ht.Add(p.Id, p.ProcessName)
                    );
                this._isExcelActive = true;
            }
            else this._isExcelActive = false;

        }//

        /// <summary>
        /// Mata el proceso de Excel
        /// </summary>
        public void KillExcel()
        {
            try
            {
                Process p = new Process();
                p.StartInfo = new ProcessStartInfo();
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.FileName = "taskkill.exe";
                p.StartInfo.Arguments = "/F /IM EXCEL.EXE";
                p.StartInfo.CreateNoWindow = true;
                p.Start();
                p.WaitForExit();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }//


        //public void KillExcelProcessList()
        //{
        //    if (!this._isExcelActive)
        //        return;

        //    if (ht.Count > 0)
        //    {
        //        foreach (var item in ht.Keys)
        //        {
        //            if (Process.GetProcessesByName("excel").ToList().Contains(Process.GetProcessById(int.Parse(item.ToString()))))
        //            {
                        
        //            } 
        //        }//
        //    }
            
        //}//


    }//end class
    
}
